using System;
using System.Collections;
using System.Collections.Generic; 
using UnityEngine;
using XFABManager;

namespace XFGameFramework
{ 
    [DisallowMultipleComponent]
    public abstract class View : MonoBehaviour
    {

        #region 字段

        internal bool loaded = false;

        private Module module;

        #endregion

        #region 属性

        /// <summary>
        /// 唯一标识(只读)
        /// </summary>
        public int Id => GetInstanceID();

        /// <summary>
        /// 当前View所在的模块
        /// </summary>
        public Module Module
        {
            get 
            {
                if(loaded && module == null)
                    module = ModuleManager.GetCurrentModule();

                return module;
            }
            internal set
            { 
                module = value;
            }
        }


        /// <summary>
        /// 预制体名称
        /// </summary>
        internal string AssetName { get; set; }
         
        /// <summary>
        /// 当前View对应的数据，在View被回收时，该数据也会被移除!
        /// </summary>
        public virtual Model Model { get; }

        #endregion

        #region 事件

        [Tooltip("View被移除时触发")]
        public Action onViewRemove;

        #endregion

        #region 生命周期

        protected virtual void Start() 
        { 
            CoroutineStarter.Start(StartCoroutine()); 
        }

        protected virtual void OnDestroy()
        {
            if (!ApplicationTool.isPlaying) return;

            if (Module != null && loaded)
            {
                // 移除View
                ViewManager.RemoveView(Module, this); 
            }
        }

        protected virtual void OnEnable()
        {
            //RegisterEvents();
        }

        protected virtual void OnDisable()
        {
            //UnRegisterEvents();
        }

        #endregion

        #region 方法

        /// <summary>
        /// 关闭View(这里的关闭并不是销毁,而是放到缓存池中,所以不用担心销毁和创建的开销)
        /// </summary>
        public virtual void Close()
        {
            if (this.IsDestroy()) return;
            if (gameObject.IsDestroy()) return;
            // 如果是false 说明已经关闭,直接return 就可以了
            if (!loaded) return; 
            loaded = false; 
            if (Module != null)
            {
                // 移除View
                ViewManager.RemoveView(Module, this);
                //// 移除数据 
                //ModelManager.RemoveModel(Module, model);
            }

            GameObjectLoader.UnLoad(gameObject); 
        }


        /// <summary>
        /// 加载完成的回调(可以在当前方法中做一些数据更新的逻辑)
        /// </summary>
        /// <param name="param">加载View时传递的参数</param>
        public virtual void OnLoaded(params object[] param) 
        { 
        }

        /// <summary>
        /// View被回收 或 被移除时调用
        /// </summary>
        public virtual void OnRemove() {
          
        }

      
        [Obsolete("已过时,请使用 EventManager.AddEvent 和  EventManager.RemoveEvent 来添加 或 移除事件!", true)]
        protected void RegisterEvent(string eventName, Action<object[]> callback) 
        { 
        }

        [Obsolete("已过时,请使用 EventManager.AddEvent 和  EventManager.RemoveEvent 来添加 或 移除事件!",true)]
        protected void RegisterEvent(int event_name_hash, Action<object[]> callback)
        { 
        }
         
        private IEnumerator StartCoroutine()
        {
            while (Module == null) 
            {  
                if (transform.parent != null)
                {
                    // 尝试去父节点中查找
                    View view = transform.parent.GetComponentInParent<View>();
                    if (view != null)
                    {
                        Module = view.Module;
                    }
                    else
                    { 
                        Module = ModuleManager.GetCurrentModule();
                    } 
                }
                else 
                {  
                    Module = ModuleManager.GetCurrentModule();
                }

                if(Module == null)
                    yield return null;  
            }
             
            if (loaded == false)
            {
                loaded = true;
                OnLoaded(null);
            } 
        }

        internal void Remove() {
            onViewRemove?.Invoke();
            OnRemove();
        }

        #endregion
    }
}